#version 450 core
#extension GL_ARB_explicit_uniform_location : require
#define NUM_MAX_LIGHTS 8

layout(location = 0) in vec3 normal;
layout(location = 1) in vec3 fragPos;
layout(location = 0) out vec4 fragColor;

struct World {
    vec3 cameraPos;
    mat4 matVP;
};
struct Transform {
    mat4 modelMatrix;
    mat4 mvpMatrix;
    mat4 normalMatrix;
};
struct Light {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    vec3 position;
};
struct Material {
    vec3 color;
    float shiness;
};

layout(binding = 0, std140) uniform WorldBlock {
    World world;
};
layout(binding = 1, std140) uniform LightBlock {
    Light light[NUM_MAX_LIGHTS];
};
layout(location = 0) uniform Transform transform;
layout(location = 3) uniform Material material;
layout(location = 5) uniform uint numLights;

void main() {
    vec3 result = vec3(0.0);
    for (uint i = 0; i < numLights; ++i) {
        vec3 ambient = light[i].ambient * material.color;
        vec3 lightDir = normalize(light[i].position - fragPos);
        vec3 diffuse = max(dot(lightDir, normal), 0.0f) * light[i].diffuse;
        vec3 reflectDir = reflect(-lightDir, normal);
        vec3 viewDir = normalize(world.cameraPos - fragPos);
        float spec = pow(max(dot(viewDir, reflectDir), 0.0f), material.shiness);
        vec3 specular = spec * light[i].specular * material.color;
        result += (ambient + diffuse + specular);
    }
    fragColor = vec4(result, 1.0f);
}
